package com.sky.service.impl;

import com.alibaba.druid.util.StringUtils;
import com.google.common.base.Joiner;
import com.sky.entity.Orders;
import com.sky.mapper.OrdersMapper;
import com.sky.mapper.UserMapper;
import com.sky.service.ReportService;
import com.sky.vo.MyBusinessDataVo;
import com.sky.vo.OrderReportVO;
import com.sky.vo.TurnoverReportVO;
import com.sky.vo.UserReportVO;
import org.apache.coyote.Response;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.math.BigDecimal;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Service
public class ReportServiceImpl implements ReportService {

    @Autowired
    private OrdersMapper ordersMapper;
    @Autowired
    private UserMapper userMapper;
    //查询指定日期内的营业额
    public TurnoverReportVO getTurnOver(LocalDate begin, LocalDate end) {
        //根据时间区间查找每个日期的总收入
        List<Map> map = ordersMapper.getTurnOver(begin,end);
        //设置begin和end之间的时间
        List<LocalDate> dates = new ArrayList<>();
        while (!begin.equals(end)){
            dates.add(begin);
            begin = begin.plusDays(1);
        }
        dates.add(begin);
        //遍历begin和end之间的时间，构造每个日期的薪资字符串
        List<BigDecimal> moneys = new ArrayList<>();
        for (LocalDate date : dates){//遍历每个日期
            int flag = -1;//判断当前日期是否有营业额
            for (Map map1 : map){//遍历每个日期收入收入
                LocalDate temDate = LocalDate.parse((String)map1.get("date1")) ;//日期
                BigDecimal temBDe = (BigDecimal) map1.get("money");
                //判断日期是否相等
                if(date.equals(temDate)){
                    moneys.add(temBDe);//把当前日期营业额放入集合
                    flag = 1;
                    break;
                }
            }
            if(flag == -1){
                moneys.add(new BigDecimal(0.0));
            }
        }

        return TurnoverReportVO.builder()
                .dateList(Joiner.on(",").join(dates))
                .turnoverList(Joiner.on(",").join(moneys))
                .build();
    }

    //统计指定日期内的用户和新增用户
    @Override
    public UserReportVO getUserStatistics(LocalDate begin, LocalDate end) {
        //查询指定日期内的每天注册的用户量(分组查询)
        List<Map> usersNew = userMapper.getUserStatistics(begin,end);
        //查询查询开始日期前一天的用户总量
        int preAmount = userMapper.getUserCountBytTime(begin.plusDays(-1));//
        //创建指定日期区间的所有日期集合
        ArrayList<LocalDate> dates = new ArrayList<>();
        while (!begin.equals(end)){
            dates.add(begin);
            begin = begin.plusDays(1);
        }
        dates.add(begin);
        //循环遍历，前一天用户总量+当前天新增用户量=当前天用户总量
        ArrayList<Integer> userAll = new ArrayList<>();//总用户量
        ArrayList<Integer> userOneDay = new ArrayList<>();//每天新增
        for (LocalDate date: dates){//遍历所有日期
            int flag = -1;
            for (Map tem : usersNew){
                LocalDate temDate = LocalDate.parse((String)tem.get("date1")) ;//日期
                int temUserOneDay = Integer.parseInt(String.valueOf(tem.get("userAll")));//每天新增用户
                if(date.equals(temDate)){//二者相等
                    preAmount = preAmount + temUserOneDay;
                    userAll.add(preAmount);//当天的用户总量
                    userOneDay.add(temUserOneDay);//每天新增用户
                    flag = 1;
                    break;
                }
            }
            if(flag == -1){//没有新增
                userOneDay.add(0);
                userAll.add(preAmount);

            }
        }
        return UserReportVO.builder()
                .dateList(Joiner.on(",").join(dates))
                .totalUserList(Joiner.on(",").join(userAll))
                .newUserList(Joiner.on(",").join(userOneDay))
                .build();
    }

    //导出近30天营业数据
    public void exportBusinessData(HttpServletResponse response) throws IOException {
        //1.查询近30天营业数据
        //查询概览数据:营业额、订单完成率、新增用户、有效订单数
        LocalDate dataBegin = LocalDate.now().minusDays(30);//今天向前30天
        LocalDate dataEnd = LocalDate.now().minusDays(1);//向前一天
        //获取订单信息，LocalDateTime.of(dataBegin, LocalTime.MIN)给日期设置为0点0分0秒
        List<Map> ordersCount = ordersMapper.
                getOrdersCount(LocalDateTime.of(dataBegin, LocalTime.MIN),
                        LocalDateTime.of(dataEnd, LocalTime.MAX));
        //遍历map集合
        double turnOver = 0.0;//营业额
        int validOrderCount = 0;//有效订单数
        int allOrderCount = 0;//总订单数
        int userNew = 0;//新增用户
        for (Map map: ordersCount){
            int status = (Integer) map.get("status");//订单状态
            int count = Integer.parseInt(String.valueOf(map.get("mount"))) ;//该状态的订单数量
            double money = Double.parseDouble(String.valueOf( map.get("money")));//该状态下的总金额
            if (status == Orders.COMPLETED){//已完成订单
                validOrderCount += count;//有效订单数
                turnOver += money;//营业额
            }
            allOrderCount += count;//总订单数
        }
        //查询新增的用户
        userNew = userMapper.getUserCountOnTime(dataBegin,dataEnd);

        //查询明细数据：日期、营业额、有效订单、订单完成率、平均客单价、新增用户数
        List<Map> orderCountEveryDay = ordersMapper.getOrderCountEveryDay(dataBegin, dataEnd);//查询订单明细
        List<Map> userStatistics = userMapper.getUserStatistics(dataBegin, dataEnd);//查询指定日期内每天的新增用户
        List<MyBusinessDataVo> businessDataVos = new ArrayList<>();//存放明细数据
        for (int i = 0; i < 30; i ++){
            String tem = dataBegin.plusDays(i).toString();//第i+1天
            MyBusinessDataVo vo ;
            double turnOver1 = 0.0;//营业额
            int validOrderCount1 = 0;//有效订单数
            int allOrderCount1 = 0;//总订单数
            int userNew1 = 0;//新增用户
            int flag = -1,flagd = -1;//标记当天是否存在数据
            for (Map map : orderCountEveryDay){//把查询到的放入类中
                String date = (String) map.get("date");
                int status = (Integer) map.get("status");//订单状态
                int count = Integer.parseInt(String.valueOf(map.get("amount"))) ;//该状态的订单数量
                double money = Double.parseDouble(String.valueOf( map.get("money")));//该状态下的总金额
                if(tem.equals(date)){//日期相等
                    flag = 1;
                    if (status == Orders.COMPLETED){//已完成订单
                        validOrderCount1 += count;//有效订单数
                        turnOver1 += money;//营业额
                    }
                    allOrderCount1 += count;//总订单数
                }
            }
            if (flag == -1){
                vo = MyBusinessDataVo.builder().date(tem)
                        .turnOver(0.0)
                        .validOrderCount(0)
                        .completeLvOrder(0.0)
                        .unitPrice(0.0)
                        .allOrderCount(0).build();
            }else {
                vo = MyBusinessDataVo.builder().date(tem).turnOver(turnOver1).validOrderCount(validOrderCount1)
                        .completeLvOrder((double)validOrderCount1/allOrderCount1).build();
                //判断是否有有效订单
                if (validOrderCount1 == 0){
                    vo.setUnitPrice(0.0);
                }else {
                    vo.setUnitPrice(turnOver1/validOrderCount1);
                }
            }
            //遍历每日新增用户啊
            for (Map map : userStatistics){
                if(tem.equals(map.get("date1"))){
                    vo.setUserNew(Integer.parseInt(String.valueOf(map.get("userAll"))) );
                    flagd = 1;
                    break;
                }
            }
            if (flagd == -1){
                vo.setUserNew(0);
            }
            businessDataVos.add(vo);
        }




        //2.将数据写入excel表中
        //获取excel模板
        InputStream inp = this.getClass().getClassLoader().getResourceAsStream("template/运营数据报表模板.xlsx");
        XSSFWorkbook excel = new XSSFWorkbook(inp);
        XSSFSheet sheet = excel.getSheetAt(0);//获取第一个sheet表
        //添加日期和概述数据
        sheet.getRow(1).getCell(1).setCellValue("日期:"+dataBegin+"-"+dataEnd);//设置日期
        sheet.getRow(3).getCell(2).setCellValue(turnOver);//营业额
        sheet.getRow(3).getCell(4).setCellValue(((double)validOrderCount/allOrderCount*100)+"%");//订单完成率
        sheet.getRow(3).getCell(6).setCellValue(userNew);//新增用户
        sheet.getRow(4).getCell(2).setCellValue(validOrderCount);//有效订单数
        sheet.getRow(4).getCell(4).setCellValue((double)turnOver/validOrderCount);//平均客单价

        //添加明细数据
        for (int i = 0; i < businessDataVos.size(); i++){
            MyBusinessDataVo vo = businessDataVos.get(i);
            sheet.getRow(7+i).getCell(1).setCellValue(vo.getDate());
            sheet.getRow(7+i).getCell(2).setCellValue(vo.getTurnOver());
            sheet.getRow(7+i).getCell(3).setCellValue(vo.getValidOrderCount());
            sheet.getRow(7+i).getCell(4).setCellValue(vo.getCompleteLvOrder());
            sheet.getRow(7+i).getCell(5).setCellValue(vo.getUnitPrice());
            sheet.getRow(7+i).getCell(6).setCellValue(vo.getUserNew());

        }

        //3.将excel表下载下来
        ServletOutputStream out = response.getOutputStream();
        excel.write(out);
        //4.关闭资源
        out.close();
        excel.close();
    }
}
